package com.zzyk.main.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyk.main.configuration.exception.UserException;
import com.zzyk.main.mapper.DeviceGroupMapper;
import com.zzyk.main.mapper.DeviceMapper;
import com.zzyk.main.mapper.GroupDeviceMapper;
import com.zzyk.main.model.pojo.Device;
import com.zzyk.main.model.pojo.DeviceGroup;
import com.zzyk.main.model.pojo.DeviceGroupDeviceType;
import com.zzyk.main.model.pojo.GroupDevice;
import com.zzyk.main.model.vo.DeviceTypeVO;
import com.zzyk.main.service.DeviceGroupDeviceTypeService;
import com.zzyk.main.service.GroupDeviceService;
import com.zzyk.main.utils.ArrayUtilS;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class GroupDeviceServiceImpl extends ServiceImpl<GroupDeviceMapper, GroupDevice> implements GroupDeviceService {
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private DeviceGroupMapper deviceGroupMapper;
    @Resource
    private DeviceGroupDeviceTypeService deviceGroupDeviceTypeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addGroupDevice(String data, DeviceGroup deviceGroup) throws UserException {
        JSONArray jsonObject = new JSONArray(data);
        if (jsonObject.size() < 1) {
            /*如果传过来的为空 那么去把这个分组下面的所有设备删除*/
            deviceGroupDeviceTypeService.remove(new LambdaQueryWrapper<DeviceGroupDeviceType>().eq(DeviceGroupDeviceType::getGroup, deviceGroup.getId()));
            remove(new LambdaQueryWrapper<GroupDevice>().eq(GroupDevice::getGroup, deviceGroup.getId()));
            deviceGroupMapper.setNull(deviceGroup);
            return true;
        }
        List<DeviceTypeVO> deviceTypeVOS = jsonObject.toList(DeviceTypeVO.class);
        List<Integer> integers = jsonArrayToList(deviceTypeVOS);
        /*首先获取原本的设备类型树*/
        String tree = deviceGroup.getTreejson();
        deviceGroupDeviceTypeService.remove(new LambdaQueryWrapper<DeviceGroupDeviceType>().eq(DeviceGroupDeviceType::getGroup, deviceGroup.getId()));
        List<DeviceGroupDeviceType> deviceGroupDeviceTypes = new ArrayList<>();
        for (Integer deviceType : integers) {
            DeviceGroupDeviceType deviceGroupDeviceType = new DeviceGroupDeviceType();
            deviceGroupDeviceType.setGroup(deviceGroup.getId());
            deviceGroupDeviceType.setDeviceType(deviceType);
            deviceGroupDeviceTypes.add(deviceGroupDeviceType);
        }
        deviceGroupDeviceTypeService.saveBatch(deviceGroupDeviceTypes);
        /*判断这两个是否相等*/
        if (!data.equals(tree)) {
            Set<Integer> childNodes = getChildNodes(deviceTypeVOS);
            deviceGroup.setSelectedNode(setNodeString(childNodes));
            /*如果不相等就把新的赋值进去*/
            deviceGroup.setTreejson(data);
            /*然后去判断少了哪写设备类型*/
            /*先将原本的数据遍历出来设备分组*/
            JSONArray jsonTree = new JSONArray(tree);
            List<DeviceTypeVO> treeList = jsonTree.toList(DeviceTypeVO.class);
            /*拿出来原本的设备类型ID*/
            List<Integer> treeTypeList = jsonArrayToList(treeList);
            /*拿出原本的和新传入的不一样的ID 那么这就是取 哪些类型取消勾选了*/
            List<Integer> cancel = ArrayUtilS.subtraction(treeTypeList, integers);
            /*拿出新传入的和原本的比不一样的ID 那么这就是取 新加了哪些类型*/
            List<Integer> add = ArrayUtilS.subtraction(integers, treeTypeList);
            /*修改treeJson*/
            deviceGroupMapper.updateById(deviceGroup);
            /*然后去删除取消勾选的设备*/
            if (cancel.size() > 0) {
                deviceGroupMapper.deleteByDeviceType(cancel, deviceGroup.getOrganization());
            }
            if (cancel.contains(0)) {
                deviceGroupMapper.deleteByDeviceType(null, deviceGroup.getOrganization());
            }
            if (add.size() > 0) {
                /*然后去添加新勾选的设备类型的设备*/
                List<Device> devices = deviceMapper.selectAllInDeviceType(add, deviceGroup.getOrganization());
                if (add.contains(0)) {
                    List<Device> notType = deviceMapper.selectAllByEnterpiseAndNotType(deviceGroup.getOrganization());
                    devices.addAll(notType);
                }
                if (ObjectUtil.isNotNull(devices) && !devices.isEmpty()) {
                    Set<GroupDevice> list = new HashSet<>();
                    for (Device device : devices) {
                        GroupDevice groupDevice = new GroupDevice();
                        groupDevice.setDevice(device.getId());
                        groupDevice.setGroup(deviceGroup.getId());
                        list.add(groupDevice);
                    }
                    return saveBatch(list);
                }
            } else {
                return true;
            }
        } else {
            return true;
        }
        throw new UserException("本企业无该类型生产设备，无法添加。");
    }

    private String setNodeString(Set<Integer> area) {
        StringBuffer buffer = new StringBuffer();
        for (Integer str : area) {
            buffer.append(str).append(",");
        }
        buffer.deleteCharAt(buffer.length() - 1);
        return buffer.toString();
    }

    private Set<Integer> getChildNodes(List<DeviceTypeVO> deviceTypeVOS) {
        Set<Integer> list = new HashSet<>();
        for (DeviceTypeVO deviceTypeVO : deviceTypeVOS) {
            if (ObjectUtil.isNull(deviceTypeVO.getChildren()) || deviceTypeVO.getChildren().isEmpty()) {
                list.add(deviceTypeVO.getId());
            } else {
                for (DeviceTypeVO child : deviceTypeVO.getChildren()) {
                    if (ObjectUtil.isNull(child.getChildren()) || child.getChildren().isEmpty()) {
                        list.add(child.getId());
                    } else {
                        for (DeviceTypeVO child2 : child.getChildren()) {
                            if (ObjectUtil.isNull(child2.getChildren()) || child2.getChildren().isEmpty()) {
                                list.add(child2.getId());
                            } else {
                                for (DeviceTypeVO child3 : child2.getChildren()) {
                                    list.add(child3.getId());
                                }
                            }
                        }
                    }
                }
            }
        }
        return list;

    }

    private List<Integer> jsonArrayToList(List<DeviceTypeVO> deviceTypeVOS) {
        List<Integer> list = new ArrayList<>();
        for (DeviceTypeVO deviceTypeVO : deviceTypeVOS) {
            if (ObjectUtil.isNull(deviceTypeVO.getChildren()) || deviceTypeVO.getChildren().isEmpty()) {
                list.add(deviceTypeVO.getId());
            } else {
                list.add(deviceTypeVO.getId());
                for (DeviceTypeVO child : deviceTypeVO.getChildren()) {
                    if (ObjectUtil.isNull(child.getChildren()) || child.getChildren().isEmpty()) {
                        list.add(child.getId());
                    } else {
                        list.add(child.getId());
                        for (DeviceTypeVO child2 : child.getChildren()) {
                            if (ObjectUtil.isNull(child2.getChildren()) || child2.getChildren().isEmpty()) {
                                list.add(child2.getId());
                            } else {
                                list.add(child2.getId());
                                for (DeviceTypeVO child3 : child2.getChildren()) {
                                    list.add(child3.getId());
                                }
                            }
                        }
                    }
                }
            }
        }
        return list;
    }
}
